package com.gitee.qdbp.jdbc.stream;

import java.util.List;
import com.gitee.qdbp.able.exception.ServiceException;
import com.gitee.qdbp.jdbc.api.CrudDao;
import com.gitee.qdbp.jdbc.model.ValidStrategy;

/**
 * 实体数组后续操作: insert / update
 *
 * @author zhaohuihua
 * @version 20210530
 */
public class CrudOnAfterEntitiesStream<T> {

    protected final CrudDao<T> dao;
    private final List<?> entities;

    CrudOnAfterEntitiesStream(CrudDao<T> dao, List<?> entities) {
        this.dao = dao;
        this.entities = entities;
    }

    /**
     * 批量保存实体对象<br>
     * 注意: 如果主键编号为空将会自动生成<br>
     * 注意: 默认创建参数由entityFieldFillExecutor添加, 如dataState=DataState.NORMAL<br>
     * 注意: 根据实现类的不同, 有以下注意事项, 请详查具体实现类的机制:<br>
     * -- 大部分的实现类要求实体列表字段对齐<br>
     * ---- 例如第1个实体有abcd四个字段,第2个实体只有abc三个字段, 则第2个实体的d字段将被设置为NULL<br>
     * ---- 这将会导致数据库设置的默认值不会生效, 因此需要手动设置d字段, 或在d字段上配置默认值<br>
     * entities 实体对象列表(只能是entity或map或IdEntity列表, 其他参数将会报错)<br>
     * <pre>
    List&lt;String&gt; ids = qdbcBoot.crudStream(SysUser.class)
        .entities(user)
        .insert();
     * </pre>
     * 
     * @return 返回主键编号
     * @throws ServiceException 操作失败
     */
    public List<String> insert() throws ServiceException {
        return dao.inserts(entities);
    }

    /**
     * 批量保存实体对象<br>
     * 注意: 如果主键编号为空将会自动生成<br>
     * 注意: 默认创建参数由entityFieldFillExecutor添加, 如dataState=DataState.NORMAL<br>
     * 注意: 根据实现类的不同, 有以下注意事项, 请详查具体实现类的机制:<br>
     * -- 大部分的实现类要求实体列表字段对齐<br>
     * ---- 例如第1个实体有abcd四个字段,第2个实体只有abc三个字段, 则第2个实体的d字段将被设置为NULL<br>
     * ---- 这将会导致数据库设置的默认值不会生效, 因此需要手动设置d字段, 或在d字段上配置默认值<br>
     * entities 实体对象列表(只能是entity或map或IdEntity列表, 其他参数将会报错)<br>
     * <pre>
    List&lt;String&gt; ids = qdbcBoot.crudStream(SysUser.class)
        .entities(user)
        .insert();
     * </pre>
     * 
     * @param fillCreateParams 是否自动填充创建参数(创建人/创建时间等)
     * @return 返回主键编号
     * @throws ServiceException 操作失败
     */
    public List<String> insert(boolean fillCreateParams) throws ServiceException {
        return dao.inserts(entities, fillCreateParams);
    }

    /**
     * 批量保存实体对象<br>
     * 注意: 如果主键编号为空将会自动生成<br>
     * 注意: 默认创建参数由entityFieldFillExecutor添加, 如dataState=DataState.NORMAL<br>
     * 注意: 根据实现类的不同, 有以下注意事项, 请详查具体实现类的机制:<br>
     * -- 大部分的实现类要求实体列表字段对齐<br>
     * ---- 例如第1个实体有abcd四个字段,第2个实体只有abc三个字段, 则第2个实体的d字段将被设置为NULL<br>
     * ---- 这将会导致数据库设置的默认值不会生效, 因此需要手动设置d字段, 或在d字段上配置默认值<br>
     * entities 实体对象列表(只能是entity或map或IdEntity列表, 其他参数将会报错)<br>
     * <pre>
    List&lt;String&gt; ids = qdbcBoot.crudStream(SysUser.class)
        .entities(user)
        .insert(ValidStrategy.TRANSFORM);
     * </pre>
     * 
     * @param validStrategy 校验处理策略<br>
     *            <b>注意</b>: 由于@Column的length/precision/scale有默认值, 一旦启用, 则所有字段都需要覆盖设置!
     * @return 返回主键编号
     * @throws ServiceException 操作失败
     */
    public List<String> insert(ValidStrategy validStrategy) throws ServiceException {
        return dao.inserts(entities, validStrategy);
    }

    /**
     * 批量保存实体对象<br>
     * 注意: 如果主键编号为空将会自动生成<br>
     * 注意: 默认创建参数由entityFieldFillExecutor添加, 如dataState=DataState.NORMAL<br>
     * 注意: 根据实现类的不同, 有以下注意事项, 请详查具体实现类的机制:<br>
     * -- 大部分的实现类要求实体列表字段对齐<br>
     * ---- 例如第1个实体有abcd四个字段,第2个实体只有abc三个字段, 则第2个实体的d字段将被设置为NULL<br>
     * ---- 这将会导致数据库设置的默认值不会生效, 因此需要手动设置d字段, 或在d字段上配置默认值<br>
     * entities 实体对象列表(只能是entity或map或IdEntity列表, 其他参数将会报错)<br>
     * <pre>
    List&lt;String&gt; ids = qdbcBoot.crudStream(SysUser.class)
        .entities(user)
        .insert(ValidStrategy.TRANSFORM, true);
     * </pre>
     * 
     * @param validStrategy 校验处理策略<br>
     *            <b>注意</b>: 由于@Column的length/precision/scale有默认值, 一旦启用, 则所有字段都需要覆盖设置!
     * @param fillCreateParams 是否自动填充创建参数(创建人/创建时间等)
     * @return 返回主键编号
     * @throws ServiceException 操作失败
     */
    public List<String> insert(ValidStrategy validStrategy, boolean fillCreateParams) throws ServiceException {
        return dao.inserts(entities, validStrategy, fillCreateParams);
    }

    /**
     * 根据主键编号批量更新实体对象<br>
     * 注意: 如果主键编号为空将会报错<br>
     * 注意: 这里的限制条件只有主键编号, 而不会追加数据状态作为限制条件<br>
     * 注意: entity将会自动由entityFieldFillExecutor填充更新参数(修改人/修改时间等)<br>
     * 注意: 根据实现类的不同, 有以下注意事项, 请详查具体实现类的机制:<br>
     * -- 1.某些实现类可能无法获取到准确的受影响行数<br>
     * -- 2.大部分的实现类要求实体列表字段对齐<br>
     * ---- 例如第1个实体有abcd四个字段,第2个实体只有abc三个字段, 则第2个实体的d字段将被更新为NULL<br>
     * ---- 因此需要手动设置d字段(一般来自数据库查询的记录或用户输入的信息)<br>
     * entities 实体对象列表, 只能是entity或map或IdEntity列表, 其他参数将会报错<br>
     * 如果实体对象是map, map下不能有where, 否则将会报错 <pre>
    int rows = qdbcBoot.crudStream(SysUser.class)
        .entities(users)
        .update();
     * </pre>
     * 
     * @return 受影响行数(某些实现类可能无法获取到准确的受影响行数)
     * @throws ServiceException 操作失败
     */
    public int update() throws ServiceException {
        return dao.updates(entities);
    }

    /**
     * 根据主键编号批量更新实体对象<br>
     * 注意: 如果主键编号为空将会报错<br>
     * 注意: 这里的限制条件只有主键编号, 而不会追加数据状态作为限制条件<br>
     * 注意: entity将会自动由entityFieldFillExecutor填充更新参数(修改人/修改时间等)<br>
     * 注意: 根据实现类的不同, 有以下注意事项, 请详查具体实现类的机制:<br>
     * -- 1.某些实现类可能无法获取到准确的受影响行数<br>
     * -- 2.大部分的实现类要求实体列表字段对齐<br>
     * ---- 例如第1个实体有abcd四个字段,第2个实体只有abc三个字段, 则第2个实体的d字段将被更新为NULL<br>
     * ---- 因此需要手动设置d字段(一般来自数据库查询的记录或用户输入的信息)<br>
     * entities 实体对象列表, 只能是entity或map或IdEntity列表, 其他参数将会报错<br>
     * 如果实体对象是map, map下不能有where, 否则将会报错 <pre>
     * <pre>
    int rows = qdbcBoot.crudStream(SysUser.class)
        .entities(users)
        .update(true); // 自动填充更新参数
     * </pre>
     * 
     * @param fillUpdateParams 是否自动填充更新参数(修改人/修改时间等)
     * @return 受影响行数
     * @throws ServiceException 操作失败
     */
    public int update(boolean fillUpdateParams) throws ServiceException {
        return dao.updates(entities, fillUpdateParams);
    }

    /**
     * 根据主键编号批量更新实体对象<br>
     * 注意: 如果主键编号为空将会报错<br>
     * 注意: 这里的限制条件只有主键编号, 而不会追加数据状态作为限制条件<br>
     * 注意: entity将会自动由entityFieldFillExecutor填充更新参数(修改人/修改时间等)<br>
     * 注意: 根据实现类的不同, 有以下注意事项, 请详查具体实现类的机制:<br>
     * -- 1.某些实现类可能无法获取到准确的受影响行数<br>
     * -- 2.大部分的实现类要求实体列表字段对齐<br>
     * ---- 例如第1个实体有abcd四个字段,第2个实体只有abc三个字段, 则第2个实体的d字段将被更新为NULL<br>
     * ---- 因此需要手动设置d字段(一般来自数据库查询的记录或用户输入的信息)<br>
     * entities 实体对象列表, 只能是entity或map或IdEntity列表, 其他参数将会报错<br>
     * 如果实体对象是map, map下不能有where, 否则将会报错 <pre>
    int rows = qdbcBoot.crudStream(SysUser.class)
        .entities(users)
        .update(ValidStrategy.TRANSFORM);
     * </pre>
     * 
     * @param validStrategy 校验处理策略<br>
     *            <b>注意</b>: 由于@Column的length/precision/scale有默认值, 一旦启用, 则所有字段都需要覆盖设置!
     * @return 受影响行数(某些实现类可能无法获取到准确的受影响行数)
     * @throws ServiceException 操作失败
     */
    public int update(ValidStrategy validStrategy) throws ServiceException {
        return dao.updates(entities, validStrategy);
    }

    /**
     * 根据主键编号批量更新实体对象<br>
     * 注意: 如果主键编号为空将会报错<br>
     * 注意: 这里的限制条件只有主键编号, 而不会追加数据状态作为限制条件<br>
     * 注意: entity将会自动由entityFieldFillExecutor填充更新参数(修改人/修改时间等)<br>
     * 注意: 根据实现类的不同, 有以下注意事项, 请详查具体实现类的机制:<br>
     * -- 1.某些实现类可能无法获取到准确的受影响行数<br>
     * -- 2.大部分的实现类要求实体列表字段对齐<br>
     * ---- 例如第1个实体有abcd四个字段,第2个实体只有abc三个字段, 则第2个实体的d字段将被更新为NULL<br>
     * ---- 因此需要手动设置d字段(一般来自数据库查询的记录或用户输入的信息)<br>
     * entities 实体对象列表, 只能是entity或map或IdEntity列表, 其他参数将会报错<br>
     * 如果实体对象是map, map下不能有where, 否则将会报错 <pre>
     * <pre>
    int rows = qdbcBoot.crudStream(SysUser.class)
        .entities(users)
        .update(ValidStrategy.TRANSFORM, true); // 自动填充更新参数
     * </pre>
     * 
     * @param validStrategy 校验处理策略<br>
     *            <b>注意</b>: 由于@Column的length/precision/scale有默认值, 一旦启用, 则所有字段都需要覆盖设置!
     * @param fillUpdateParams 是否自动填充更新参数(修改人/修改时间等)
     * @return 受影响行数
     * @throws ServiceException 操作失败
     */
    public int update(ValidStrategy validStrategy, boolean fillUpdateParams) throws ServiceException {
        return dao.updates(entities, validStrategy, fillUpdateParams);
    }
}
